﻿#include"Menu.h"

//初始化界面
void InitMenu()
{
	SetConsoleTitle("简单小说编辑器v4.0正式版 By 杨神 & 冷秋秋");
	SetSize();
	full_screen();
	hidemouth();
}
 
//主页面一
void mainMenuOne()
{
	system("color f5");
	Peppa::peppa();//打印小猪佩奇
	drawMap(); //打印边框

	string text0("欢迎使用小说编辑器4.0正式版   ★ 按方向键 ↑ ↓ 移动光标 ★ 按 回车 键确认选项 ★ 按 F1 键获得帮助文档 ★   By 杨神 & 冷秋秋");
	setmouth((MAPWIDTH / 2) - (text0.size()/2), MAPHEIGHT + 1 );
	cout << text0;

	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_INTENSITY |
		BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY);
	string text1("简单小说编辑器4.0正式版");
	string text2("1、打开小说文件");
	string text3("2、退出程序");
	
	setmouth((MAPWIDTH / 2) - (text1.size() / 2), (MAPHEIGHT / 20) + 33);
	cout << text1;
	setmouth((MAPWIDTH / 2) - (text2.size() / 2), (MAPHEIGHT / 20) + 33 + 2);
	cout << text2;
	setmouth((MAPWIDTH / 2) - (text3.size() / 2), (MAPHEIGHT / 20) + 33 + 4);
	cout << text3;

	string text4("←");
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY |
		BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY);
	setmouth((MAPWIDTH / 2) + (text2.size() / 2) + 6, (MAPHEIGHT / 20) + 33 + 2);
	cout << text4;

	while (1) //键盘响应事件
	{
		int keyboards = GetKeyboard();
		static int MainNumbers = 1;

		if (keyboards == VK_UP)   //当按下方向键上时 
		{
			/*可扩展代码*/
			if (MainNumbers > 1)
			{
				MainNumbers--;
				setmouth((MAPWIDTH / 2) + (text2.size() / 2) + 6, (MAPHEIGHT / 20) + 33 + 4);
				cout << "  ";
			}
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED  | FOREGROUND_INTENSITY |
				BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY);
			setmouth((MAPWIDTH / 2) + (text2.size() / 2) + 6, (MAPHEIGHT / 20) + 33 + 2);
			cout << text4;
			/*可扩展代码*/
		}
		else if (keyboards == VK_DOWN)   //当按下方向键下时 
		{
			/*可扩展代码*/
			if (MainNumbers < 2)
			{
				MainNumbers++;
				setmouth((MAPWIDTH / 2) + (text2.size() / 2) + 6, (MAPHEIGHT / 20) + 33 + 2);
				cout << "  ";
			}
			setmouth((MAPWIDTH / 2) + (text2.size() / 2) + 6, (MAPHEIGHT / 20) + 33 + 4);
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY |
				BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY);
			cout << text4;
			/*可扩展代码*/
		}
		else if (keyboards == VK_RETURN)  //当按下回车键时 
		{
			if (MainNumbers == 1)
			{	
				/*可扩展代码*/
				clearSomething(MAPWIDTH / 5 + 4, MAPWIDTH * 4 / 5, (MAPHEIGHT / 20) + 33, (MAPHEIGHT / 20) + 40);

				//设置颜色为白色
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN | 
					FOREGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY);

				//边框的坐标
				int left = (MAPWIDTH / 5 + MIDWIDTH * 2 / 7) % 2 ? (MAPWIDTH / 5 + MIDWIDTH * 2 / 7) + 1 : (MAPWIDTH / 5 + MIDWIDTH * 2 / 7);
				int right = (MAPWIDTH * 4 / 5 - MIDWIDTH * 2 / 7) % 2 ? (MAPWIDTH * 4 / 5 - MIDWIDTH * 2 / 7) + 1 : (MAPWIDTH * 4 / 5 - MIDWIDTH * 2 / 7);
				int up = (MAPHEIGHT / 20) + 33;
				int down = MAPHEIGHT - 2;

				//打印边框
				for (int i = left; i <= right;i += 2)//i+=2是因为横向占用的是两个位置
				{
					setmouth(i, (MAPHEIGHT / 20) + 33);
					printf("★");
					setmouth(i, MAPHEIGHT - 2);
					printf("★");
				}
				for (int i = up; i <= down; i++)
				{
					setmouth(left, i);
					printf("★");
					setmouth(right, i);
					printf("★");
				}

				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN |
					FOREGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY);

				string text4("简单小说编辑器4.0正式版");
				string text5("请输入打开小说文件");
				string text6("_____________________");

				setmouth(left + ((right - left) / 2) - (text4.size() / 2), up + (down - up) / 3);
				cout << text4;
				setmouth(left + ((right - left) / 2) - (text5.size() / 2), up + (down - up) / 3 + 2);
				cout << text5;
				setmouth(left + ((right - left) / 2) - (text6.size() / 2), up + (down - up) / 3 + 4);
				cout << text6;
				setmouth(left + ((right - left) / 2) - (text6.size() / 2), up + (down - up) / 3 + 4);

				/*可扩展代码*/

				return;
			}
			else if (MainNumbers == 2)
			{
				/*可扩展代码*/

				exit(0);
				/*可扩展代码*/
			}
		}

	}
}

void mainMenuTwo()
{
	system("color f5");
	drawMap(); //打印边框

	string text0("★ 欢迎使用小说编辑器4.0正式版 ★");
	string text1("★ By 杨神& 冷秋秋 ★");
	string text2("★ 按 F2   键查找文本 ★"); 
	string text3("★ 按 UP   键向上翻页 ★");
	string text4("★ 按 DWON 键向下翻页 ★");
	string text5("★ 按 INS  键插入文本 ★");
	string text6("★ 按 DEL  键删除文本 ★");
	string text7("★ 按shift + :键进入命令模式 ★");

	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN |
		FOREGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY);

	setmouth(MAPWIDTH * 4 / 5 + (MAPWIDTH - MAPWIDTH * 4 / 5) / 2 - (text0.size()/ 2) + 1, MAPHEIGHT / 4);
	cout << text0;
	setmouth(MAPWIDTH * 4 / 5 + (MAPWIDTH - MAPWIDTH * 4 / 5) / 2 - (text1.size() / 2) + 1, MAPHEIGHT / 4 + 4);
	cout << text1;
	setmouth(MAPWIDTH * 4 / 5 + (MAPWIDTH - MAPWIDTH * 4 / 5) / 2 - (text2.size() / 2) + 1, MAPHEIGHT / 4 + 8);
	cout << text2;
	setmouth(MAPWIDTH * 4 / 5 + (MAPWIDTH - MAPWIDTH * 4 / 5) / 2 - (text3.size() / 2) + 1, MAPHEIGHT / 4 + 12);
	cout << text3;
	setmouth(MAPWIDTH * 4 / 5 + (MAPWIDTH - MAPWIDTH * 4 / 5) / 2 - (text4.size() / 2) + 1, MAPHEIGHT / 4 + 16);
	cout << text4;
	setmouth(MAPWIDTH * 4 / 5 + (MAPWIDTH - MAPWIDTH * 4 / 5) / 2 - (text5.size() / 2) + 1, MAPHEIGHT / 4 + 20);
	cout << text5;
	setmouth(MAPWIDTH * 4 / 5 + (MAPWIDTH - MAPWIDTH * 4 / 5) / 2 - (text6.size() / 2) + 1, MAPHEIGHT / 4 + 24);
	cout << text6;
	setmouth(MAPWIDTH * 4 / 5 + (MAPWIDTH - MAPWIDTH * 4 / 5) / 2 - (text7.size() / 2) + 1, MAPHEIGHT / 4 + 28);
	cout << text7;

	return;
}

/*光标操作*/

//设置光标位置
void setmouth(int x, int y)
{
	COORD coord;
	coord.X = x;  //第3列
	coord.Y = y;  //第3行
	//获取控制台缓冲区句柄
	HANDLE ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
	//设置光标位置
	SetConsoleCursorPosition(ConsoleHandle, coord);
}

//隐藏光标
void hidemouth()
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息
	CursorInfo.bVisible = 0; //隐藏控制台光标
	SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态

}

//显示光标
void viewmouth()
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息
	CursorInfo.bVisible = 1; //隐藏控制台光标
	SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态

}

//获取当前光标位置
MouthLocation getmouth()
{
	CONSOLE_SCREEN_BUFFER_INFO pBuffer;

	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &pBuffer);

	return MouthLocation(pBuffer.dwCursorPosition.X, pBuffer.dwCursorPosition.Y);
}

/*光标操作*/

void drawMap()
{
	//打印上下边框
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY|BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY);
	
	int left = (MAPWIDTH / 5) % 2 ? MAPWIDTH / 5 + 1 : MAPWIDTH / 5;
	int right = (MAPWIDTH * 4 / 5) % 2 ? MAPWIDTH * 4 / 5 + 1 : MAPWIDTH * 4 / 5;

	for (int i = 0; i <= MAPWIDTH; i += 2)//i+=2是因为横向占用的是两个位置
	{
		//将光标移动依次到(i,0)处打印上边框
		setmouth(i, 0);
		printf("★");
		//将光标移动依次到(i,MAPHEIGHT)处打印下边框
		setmouth(i, MAPHEIGHT);
		printf("★");
		setmouth(i, MAPHEIGHT + 2);
		printf("★");
	}
	//打印左右边框
	for (int i = 1; i < MAPHEIGHT; i++)
	{
		setmouth(left, i);
		printf("★");
		setmouth(right, i);
		printf("★");
		//将光标移动依次到(MAPWIDTH, i)处打印左边框
	}

}

//全屏幕
void full_screen()
{
	HWND hwnd = GetForegroundWindow();
	int cx = GetSystemMetrics(SM_CXSCREEN);            /* 屏幕宽度 像素 */
	int cy = GetSystemMetrics(SM_CYSCREEN);            /* 屏幕高度 像素 */

	LONG l_WinStyle = GetWindowLong(hwnd, GWL_STYLE);   /* 获取窗口信息 */
	/* 设置窗口信息 最大化 取消标题栏及边框 */
	SetWindowLong(hwnd, GWL_STYLE, (l_WinStyle | WS_POPUP | WS_MAXIMIZE) & ~WS_CAPTION & ~WS_THICKFRAME & ~WS_BORDER);

	SetWindowPos(hwnd, HWND_TOP, 0, 0, cx, cy, 0);
}

//关闭滚动条
void SetSize()
{
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos = { MAPWIDTH, MAPHEIGHT };
	SMALL_RECT rc = { 0, 0, MAPWIDTH - 1, MAPHEIGHT - 1 };
	SetConsoleWindowInfo(hOut, true, &rc);
	SetConsoleScreenBufferSize(hOut, pos);
}

int GetKeyboard()
{
	HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);      //获得标准输入设备句柄  
	INPUT_RECORD keyrec;                                    //定义输入事件结构体  
	DWORD res;                                              //定义返回记录  

	ReadConsoleInput(handle_in, &keyrec, 1, &res);      //读取输入事件  
	if (keyrec.EventType == KEY_EVENT  
		&& keyrec.Event.KeyEvent.bKeyDown == true)  //如果当前事件是键盘事件                 
	{
		return keyrec.Event.KeyEvent.wVirtualKeyCode;
	}
}

void clearSomething(int x_start, int x_end, int y_start, int y_end)
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY |
		BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY);

	for (int j = y_start; j < y_end; j++)
	{
		setmouth(x_start, j);
		for (int i = x_start; i < x_end; i++)
		{
			cout << " ";
		}
	}
}


/*Peppa类方法*/
//生成小猪Peppa
void Peppa::peppa(int xpoint, int ypoint)
{
	int yLocation = ypoint; 
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY |
		BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY);
	for (double y = -1, s = 1; y < 0.6; y += 0.05 / s, setmouth(xpoint, yLocation++))
		for (double x = -1; x < 0.6; x += 0.025 / s)
			std::cout << " .|/=\\|/=\\| @!"[(int)f(u(x, y, 0.3), v(x, y, 0.3))];
}



/*内部方法*/
double Peppa::c(double x, double y, double r) { return sqrt(x * x + y * y) - r; }

double Peppa::u(double x, double y, double t) { return x * cos(t) + y * sin(t); }

double Peppa::v(double x, double y, double t) { return y * cos(t) - x * sin(t); }

double Peppa::fa(double x, double y) { return fmin(c(x, y, 0.5), c(x * 0.47 + 0.15, y + 0.25, 0.3)); }

double Peppa::no(double x, double y) { return c(x * 1.2 + 0.97, y + 0.25, 0.2); }

double Peppa::nh(double x, double y) {
	return fmin(c(x + 0.9, y + 0.25, 0.03),
		c(x + 0.75, y + 0.25, 0.03));
}

double Peppa::ea(double x, double y) {
	return fmin(c(x * 1.7 + 0.3, y + 0.7, 0.15),
		c(u(x, y, 0.25) * 1.7, v(x, y, 0.25) + 0.65, 0.15));
}

double Peppa::ey(double x, double y) {
	return fmin(c(x + 0.4, y + 0.35, 0.1),
		c(x + 0.15, y + 0.35, 0.1));
}

double Peppa::pu(double x, double y) { return fmin(c(x + 0.38, y + 0.33, 0.03), c(x + 0.13, y + 0.33, 0.03)); }

double Peppa::fr(double x, double y) { return c(x * 1.1 - 0.3, y + 0.1, 0.15); }

double Peppa::mo(double x, double y)
{
	return fmax(c(x + 0.15, y - 0.05, 0.2), -c(x + 0.15, y, 0.25));
}

double Peppa::o(double x, double y, double(* f)(double, double), double i) 
{
	double r = f(x, y);
	return fabs(r) < 0.02 ? (atan2(f(x, y + 1e-3) - r, f(x + 1e-3, y) - r) + 0.3) * 1.273 + 6.5 : r < 0 ? i : 0;
}

double Peppa::s(double x, double y, double(* f)(double, double), double i) { return f(x, y) < 0 ? i : 0; }

double Peppa::f(double x, double y) 
{
	return o(x, y, no, 1) ? fmax(o(x, y, no, 1),
		s(x, y, nh, 12)) : fmax(o(x, y, fa, 1),
			fmax(o(x, y, ey, 11), fmax(o(x, y, ea, 1),
				fmax(o(x, y, mo, 1),
					fmax(s(x, y, fr, 13),
						s(x, y, pu, 12))))));
}



